package mrHunter.web;

import mrHunter.*;
import mrHunter.data.JdbcMrRepository;
import mrHunter.data.JdbcProblemRepository;
import mrHunter.data.JdbcUserRepository;
import mrHunter.server.MRServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

@Controller
@RequestMapping(value = "/")
public class problemController {

    @Autowired
    JdbcProblemRepository problemRepository;

    @Autowired
    JdbcMrRepository mrRepository;

    @Autowired
    JdbcUserRepository userRepository;

    private MRInf mrInf;

    private UserInf userInf;

    private boolean newMR=true;

    //private Map<String, String> tempProInf=new HashMap<>();

    ProblemInf tempProInf;

    @RequestMapping(value = "/puzzleType/{puzzleType}",method = GET)
    public String showProblemList(@PathVariable String puzzleType, Model model,HttpServletRequest httpServletRequest){
        //ProblemList problemList=problemRepository.loadProblems();
        //userInf=(UserInf)httpServletRequest.getSession().getAttribute("user");
        //model.addAttribute(problemList);
        userInf=userRepository.findByUserName(userInf.getUsername());
        model.addAttribute(userInf);
        //return new ModelAndView("problemList","problemList",problemList);
        if(puzzleType.equals("math"))
            return "levelList";
        else if(puzzleType.equals("string"))
            return "levelList";
        else if(puzzleType.equals("graph"))
            return "levelList";
        else if(puzzleType.equals("array"))
            return "levelList";
        model.addAttribute("puzzleType", puzzleType);
        return "redirect:/puzzleType";
    }

    @RequestMapping(value = "/puzzleType",method = GET)
    public String showTypeList(Model model,HttpServletRequest httpServletRequest){
        //ProblemList problemList=problemRepository.loadProblems();
        userInf=(UserInf)httpServletRequest.getSession().getAttribute("user");
        userInf=userRepository.findByUserName(userInf.getUsername());
        //model.addAttribute(problemList);
        model.addAttribute(userInf);
        //return new ModelAndView("problemList","problemList",problemList);
        return "typeList";
    }

    @RequestMapping(value = "/puzzleType/{puzzleType}/{problemNo}",method = GET)
    public String showProblem(@PathVariable String problemNo,@PathVariable String puzzleType, Model model, HttpServletRequest request){
        tempProInf=new ProblemInf();
        System.out.println(puzzleType);
        ProblemInf problemInf=problemRepository.getProblemInf(Integer.parseInt(problemNo),puzzleType);
        //userInf=(UserInf) request.getSession().getAttribute("user");
        userInf=userRepository.findByUserName(userInf.getUsername());
        if(newMR) {
            mrInf = new MRInf(Integer.parseInt(problemNo), puzzleType, userInf.getUsername());
            newMR=false;
            mrInf.setResult("");
        }
        model.addAttribute(problemInf);
        model.addAttribute(mrInf);
        model.addAttribute(userInf);
        return "mrSubmission";
    }

    @RequestMapping(value = "/puzzleType/{puzzleType}/{problemNo}",method = POST)
    @ResponseBody
    public Map<String, Object> getProblemMR(@PathVariable String problemNo, @PathVariable String puzzleType,mrSubmission submission, Model model,HttpServletRequest request) throws IOException, ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {

        ProblemInf problemInf=problemRepository.getProblemInf(Integer.parseInt(problemNo),puzzleType);
        Map<String, Object> res=new HashMap<>();


        if(submission.getSubmitType()==2){
            newMR=true;
            String[] mr=new String[2];
            mr[0]=submission.getMr1();
            mr[1]=submission.getMr2();
            //userInf=(UserInf) request.getSession().getAttribute("user");
            mrInf.setUsername(userInf.getUsername());
            mrInf.setProblemNo(Integer.parseInt(problemNo));
            mrInf.setMR1(mr[0]);
            mrInf.setMR2(mr[1]);
            int sourceInputNum=submission.getSourceInputNum();
            int followupInputNum=submission.getFollowupInputNum();
            mrInf.setSourceInputNum(sourceInputNum);
            mrInf.setFollowUpInputNum(followupInputNum);

            MRServer mrServer=new MRServer(problemInf);

            String result=mrServer.mrServer(mr,mrInf.getSourceInputNum(),mrInf.getFollowUpInputNum());

            if(result.equals("You passed!")){
                int []levels=new int[4];
                for(int i=0;i<4;i++)
                    levels[i]=userInf.getCurrentLevel()[i];
                if(puzzleType.equals("math")){
                    levels[0]=(levels[0]==Integer.parseInt(problemNo)&&levels[0]<5)?levels[0]+1:levels[0];
                }
                else if(puzzleType.equals("string")){
                    levels[1]=(levels[1]==Integer.parseInt(problemNo)&&levels[1]<2)?levels[1]+1:levels[1];
                }
                else if(puzzleType.equals("array")){
                    levels[2]=(levels[2]==Integer.parseInt(problemNo)&&levels[2]<7)?levels[2]+1:levels[2];
                }
                else{
                    levels[3]=(levels[3]==Integer.parseInt(problemNo)&&levels[3]<2)?levels[3]+1:levels[3];
                }
                String currentLevel=levels[0]+","+levels[1]+","+levels[2]+","+levels[3];
                userInf.setCurrentLevel(levels);
                userRepository.updateCurrentLevel(userInf.getUsername(),currentLevel);
            }

            mrInf.setResult(result);
            mrInf.setFormOn(false);
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            mrInf.setTime(df.format(new Date()));
            mrRepository.save(mrInf);
            problemRepository.updateSubmit(Integer.parseInt(problemNo));

            userInf=userRepository.findByUserName(userInf.getUsername());
            res.put("result",result);
        }

        if(submission.getSubmitType()==1){
            String input=submission.getInput();
            MRServer mrServer=new MRServer();
            String output=mrServer.getOutput(problemInf.getName(),problemInf.getType(),problemNo,input);
            //ProblemInf temp=new ProblemInf();

            //Map<String, String> inputAndOutput=new HashMap<>();
            ///inputAndOutput.put(submission.getInput(),submission.getOutput());
            //tempProInf.setInputsAndOutputs(inputAndOutput);
            //tempProInf.setInputNum(problemInf.getInputNum());
            //tempProInf.setOutputNum(problemInf.getOutputNum());
            //mrInf.setInput(input);
            //mrInf.setOutput(output);
            //mrInf.setUserInAndOut(input,output);
            //mrInf.setFormOn(true);
            System.out.println(output);
            res.put("result",output);
            res.put("rowNum",submission.getRowNum());
        }

        model.addAttribute(problemInf);
        model.addAttribute(mrInf);
        //model.addAttribute(tempProInf);

        return res;
    }



    /*    @RequestMapping(value = "/levelList",method = GET)
    public String showLevelList(Model model,HttpServletRequest httpServletRequest){
        //ProblemList problemList=problemRepository.loadProblems();
        //UserInf userInf=(UserInf)httpServletRequest.getSession().getAttribute("user");
        //model.addAttribute(problemList);
        //model.addAttribute(userInf);
        //return new ModelAndView("problemList","problemList",problemList);
        return "levelList";
    }*/

   /* @RequestMapping(value = "/status",method = GET)
    public String showStatus(Model model,HttpServletRequest httpServletRequest){
        MRList mrList=mrRepository.loadMrs();
        //userInf=(UserInf)httpServletRequest.getSession().getAttribute("user");
        model.addAttribute(mrList);
        model.addAttribute(userInf);
        return "status";
    }

    @RequestMapping(value = "/test",method = GET)
    public String showTest(Model model,HttpServletRequest httpServletRequest){
        return "test";
    }

    @RequestMapping(value = "/tutorial",method = GET)
    public String showTutorial(Model model,HttpServletRequest httpServletRequest){
        //userInf=(UserInf)httpServletRequest.getSession().getAttribute("user");
        model.addAttribute(userInf);
        return "tutorial";
    }*/

}
